#pragma once

#include <vector>
#include <string>

#include "textTokens.h"

class CTextParserDefinitions;

/// Simple text tokenizer
class CTextParser
{
protected:
	/// Bracket
	struct Bracket
	{
		int		m_bracket;	//!< Bracket type
		int		m_line;		//!< Bracket line
	};

private: 
	const CTextParserDefinitions*	m_definitions;
	std::vector< Bracket >			m_brackets;
	std::string						m_file;
	int								m_line;
	int								m_level;
	int								m_numErrors;

public:
	CTextParser( const CTextParserDefinitions& definition );

	//! Process a string and generate stream of tokens
	bool Tokenize( const std::string& file, const std::string& txt, std::vector< CToken >& outTokens );

private:
	//! Internal error handling
	void EmitError( const char*message, ... );

	//! Emit token
	void EmitToken( std::vector< CToken >& outTokens, int tokenType, const std::string& data );

	//! Push/Pop bracket
	void EmitBracket( bool push, int type );

	//! Analise whitespace char, return false if we should end parsing
	bool AnalizeChar( char c );

	//! Is a newline char
	bool IsNewLine( char c ) const;

	//! Is a linefeed char
	bool IsLineFeed( char c ) const;

	//! Checks if char is number
	bool IsNum( char c ) const;

	//! Checks if char is alpha char
	bool IsAlpha( char c ) const;

	//! Checks if char is Unicode char
	bool IsUnicode( char c ) const;

	//! Check if given char is a whitespace char
	bool IsWhitespace( char c ) const;

	//! Is important char ( char that should break keyword or number parsing )
	bool IsBreakChar( char c ) const;

	//! Is integer number ?
	bool IsIntegerNumber( const char* start, int count ) const;

	//! Is floating point number ?
	bool IsFloatNumber( const char* start, int count ) const;

	//! Is it a keyword
	bool IsKeyword( const char* start, int count ) const;
};
